package fgin

import (
	"fmt"

	"github.com/hashicorp/consul/api"
)

const (
	sSERVICEWEIGHTPRIX = "fgin_service_weight" // 权重标识前缀
)

var (
	cONSULCLIENT *api.Client
)

func initConsul() {
	if fginConfig.Consul == (Consul{}) {
		// 没有服务注册中心
		return
	}
	consulClient, err := createCouslClient()
	if err != nil {
		panic(err)
	}
	// 调整端口
	port := fginConfig.Port
	if fginConfig.NetType == "http_grpc" {
		port = fginConfig.GrpcPort
	}
	// 调整服务权重
	serviceWeight := fginConfig.ServiceWeight
	if serviceWeight == 0 {
		serviceWeight = 1
	}
	// 创建服务实例
	service := &api.AgentServiceRegistration{
		ID:      genServiceId(),
		Name:    fginConfig.ServiceName,
		Tags:    []string{fginConfig.Tag, fmt.Sprintf("%s|%d", sSERVICEWEIGHTPRIX, serviceWeight)},
		Port:    fginConfig.Port,
		Address: getServiceIp(),
		Check: &api.AgentServiceCheck{
			Interval:                       "5s",
			Timeout:                        "2s",
			GRPC:                           fmt.Sprintf("%v:%v", getServiceIp(), port),
			DeregisterCriticalServiceAfter: "30s", // 如果服务失败，30s后自动删除
		},
	}

	// 注册服务到 Consul
	err = consulClient.Agent().ServiceRegister(service)
	if err != nil {
		panic(err)
	}
}

// 如果配置了consul，关闭服务的时候，主动注销服务
func deregisterService() {
	if fginConfig.NetType != "http_grpc" && fginConfig.NetType != "grpc" {
		return
	}
	if fginConfig.Consul == (Consul{}) {
		// 没有服务注册中心
		return
	}
	consulClient, err := createCouslClient()
	if err != nil {
		panic(err)
	}
	err = consulClient.Agent().ServiceDeregister(genServiceId())
	if err != nil {
		panic(err)
	}
}

// 生成consul的client
func createCouslClient() (*api.Client, error) {
	if cONSULCLIENT != nil {
		return cONSULCLIENT, nil
	}
	consulConfig := api.DefaultConfig()
	consulConfig.Address = fginConfig.Consul.Address
	consulConfig.Token = fginConfig.Consul.Token
	consulClient, err := api.NewClient(consulConfig)
	if err != nil {
		return nil, err
	}
	cONSULCLIENT = consulClient
	return consulClient, nil
}

// 获取注册使用的ip
func getServiceIp() string {
	ip := fginConfig.Consul.ServiceIp
	if ip == "" {
		ip = fginConfig.Ip
	}
	return ip
}

// 获取生成服务id
func genServiceId() string {
	port := fginConfig.Port
	if fginConfig.NetType == "http_grpc" {
		port = fginConfig.GrpcPort
	}
	return fmt.Sprintf("%s-%s:%d", fginConfig.ServiceName, getServiceIp(), port)
}
